﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.SimulationRecorderAndPlayer.SimulationPlaybackFromXML
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.PrivateImplementationDetails;
using Tecnomatix.Planning;


namespace DnProcessSimulateCommands.SimulationRecorderAndPlayer;

public class SimulationPlaybackFromXML : INotifyPropertyChanged
{
  public bool TeamCenterMode = TxTcUtilities.IsTcAnyPlatform;
  private string _currentTimer = $"0{NumberFormatInfo.CurrentInfo.NumberDecimalSeparator}0";
  private string _endTime = $"0{NumberFormatInfo.CurrentInfo.NumberDecimalSeparator}0";
  private int _jumpTimeIndex;
  private string _firstTimeStr = $"0{NumberFormatInfo.CurrentInfo.NumberDecimalSeparator}0";
  private string _timeToolTip;
  public Dictionary<int, double> IndexToTime = new Dictionary<int, double>();
  private XmlDocument _xmlDoc = new XmlDocument();
  private XmlNodeList _timeNodeList;
  private XmlNodeList _idTableRootNode;
  private string _filePath;
  private readonly string IdMapping = nameof (IdMapping);
  private readonly string TimeTag = "Time";
  private readonly string AppearancesTag = "Appearances";
  private readonly string ConsumingOperationId = nameof (ConsumingOperationId);
  private readonly string CreateTag = "Create";
  private readonly string DeleteTag = "Delete";
  private readonly string InsertTag = "Insert";
  private readonly string AttachTag = "Attach";
  private readonly string DetachTag = "Detach";
  private readonly string AttachmentParentIdAttribute = "AttachmentParentId";
  private readonly string AttachmentsTag = "Attachments";
  private readonly string ValAttribute = "Val";
  private readonly string NameAttribute = "Name";
  private readonly string IdAttribute = "Id";
  private readonly string ParentIdAttribute = "ParentId";
  private readonly string PmIdAttribute = "PmId";
  private readonly string JointsTag = "Joints";
  private readonly string HumanJointsTag = "HumanJoints";
  private readonly string HumansTag = "Humans";
  private readonly string SignalsTag = "Signals";
  private readonly string LocationsTag = "Locations";
  private readonly string LocationTag = "Location";
  private readonly string RX_Tag = "RX";
  private readonly string RY_Tag = "RY";
  private readonly string RZ_Tag = "RZ";
  private readonly string X_Tag = "X";
  private readonly string Y_Tag = "Y";
  private readonly string Z_Tag = "Z";
  private readonly string SnapshotName = "RecorderSnapshot";
  private bool _isPlaying;
  private TxSnapshot _snapshot;
  private Dictionary<string, string> _mapIdToPmId = new Dictionary<string, string>();
  private Dictionary<ITxPlcSignal, TxPlcValue> _signalValues = new Dictionary<ITxPlcSignal, TxPlcValue>();
  private Dictionary<string, TxJoint> _jointData = new Dictionary<string, TxJoint>();
  private Dictionary<string, ITxLocatableObject> _absoluteLocationData = new Dictionary<string, ITxLocatableObject>();
  private Dictionary<string, ITxHuman> _humanData = new Dictionary<string, ITxHuman>();
  private Dictionary<string, ITxPlcSignal> _signalData = new Dictionary<string, ITxPlcSignal>();
  private Dictionary<TxJoint, double> _jointValue = new Dictionary<TxJoint, double>();
  private Dictionary<string, TxTransformation> _locationValue = new Dictionary<string, TxTransformation>();
  private Dictionary<ITxHuman, Dictionary<string, double>> _humanJointData = new Dictionary<ITxHuman, Dictionary<string, double>>();
  private Dictionary<ITxDevice, TxObjectList> _drivingJoints = new Dictionary<ITxDevice, TxObjectList>();
  private Dictionary<ITxLocatableObject, ITxLocatableObject> _attachmentData = new Dictionary<ITxLocatableObject, ITxLocatableObject>();
  private Dictionary<int, Dictionary<ITxDevice, SimulationPlaybackFromXML.PoseData>> _deviceBackwardData = new Dictionary<int, Dictionary<ITxDevice, SimulationPlaybackFromXML.PoseData>>();
  private Dictionary<int, Dictionary<TxHuman, SimulationPlaybackFromXML.HumanPosture>> _humanBackwardData = new Dictionary<int, Dictionary<TxHuman, SimulationPlaybackFromXML.HumanPosture>>();
  private Dictionary<int, Dictionary<string, SimulationPlaybackFromXML.Transformation>> _locationBackwardData = new Dictionary<int, Dictionary<string, SimulationPlaybackFromXML.Transformation>>();
  private Dictionary<int, HashSet<AppearanceRestoreData>> _appearanceCreatedBackwardData = new Dictionary<int, HashSet<AppearanceRestoreData>>();
  private Dictionary<int, HashSet<AppearanceRestoreData>> _appearanceDeletedBackwardData = new Dictionary<int, HashSet<AppearanceRestoreData>>();
  private Dictionary<int, Dictionary<ITxPlcSignal, SimulationPlaybackFromXML.PlcValue>> _signalsBackwardData = new Dictionary<int, Dictionary<ITxPlcSignal, SimulationPlaybackFromXML.PlcValue>>();
  private ArrayList _timeList = new ArrayList();
  private HashSet<ITxObject> _appearances = new HashSet<ITxObject>();
  private Dictionary<string, ITxOperation> _appearancesDummyOps = new Dictionary<string, ITxOperation>();
  private Dictionary<string, Tuple<string, XmlNode>> _idsOfAppearancesMarkedForCreation = new Dictionary<string, Tuple<string, XmlNode>>();
  private Dictionary<string, HashSet<string>> _idsOfAppearancesMarkedForInsertion = new Dictionary<string, HashSet<string>>();
  private double _currTimeInterval;
  private bool _firstTimeInterval;
  private int _currentTimeIndex;
  private bool _forwardDirection = true;
  private bool _jumpTimeReached;

  public event PropertyChangedEventHandler PropertyChanged;

  protected void OnPropertyChanged(string propertyName)
  {
    PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
    if (propertyChanged == null)
      return;
    propertyChanged((object) this, new PropertyChangedEventArgs(propertyName));
  }

  public double Speed { get; set; }

  public string CurrentTimer
  {
    get => this._currentTimer;
    set
    {
      if (!(value != this._currentTimer))
        return;
      this._currentTimer = value;
      this.OnPropertyChanged(nameof (CurrentTimer));
    }
  }

  public string EndTime
  {
    get => this._endTime;
    set
    {
      this._endTime = value;
      this.OnPropertyChanged(nameof (EndTime));
    }
  }

  public int JumpTimeIndex
  {
    get => this._jumpTimeIndex;
    set
    {
      if (value == this._jumpTimeIndex)
        return;
      this._jumpTimeIndex = value;
      this.OnPropertyChanged(nameof (JumpTimeIndex));
    }
  }

  public int CurrentTimeIndex => this._currentTimeIndex;

  public string TimeToolTip
  {
    get
    {
      this._timeToolTip = SimulationRecorderAndPlayerStringTable.START_TIME_TOOLTIP + this._firstTimeStr + SimulationRecorderAndPlayerStringTable.END_TIME_TOOLTIP + this.EndTime;
      return this._timeToolTip;
    }
  }

  public string FilePath
  {
    get => this._filePath;
    set => this._filePath = value;
  }

  public event SimulationPlaybackFromXML.PlaybackFinishedEventHandler PlaybackFinished;

  public event SimulationPlaybackFromXML.PlaybackTimeIntervalReachedEventHandler PlaybackTimeIntervalReached;

  public event SimulationPlaybackFromXML.PlaybackBackwardFinishedEventHandler PlaybackBackwardFinished;

  public event SimulationPlaybackFromXML.StepForwardEventHandler StepForward;

  public event SimulationPlaybackFromXML.StepBackwardEventHandler StepBackward;

  private static T ParseOrDefault<T>(string input)
  {
    try
    {
      string s = input.Replace(',', '.');
      switch (Type.GetTypeCode(typeof (T)))
      {
        case TypeCode.Boolean:
          return (T) (ValueType) bool.Parse(s);
        case TypeCode.SByte:
          return (T) (ValueType) sbyte.Parse(s, NumberStyles.Any, (IFormatProvider) CultureInfo.InvariantCulture);
        case TypeCode.Int16:
          return (T) (ValueType) short.Parse(s, NumberStyles.Any, (IFormatProvider) CultureInfo.InvariantCulture);
        case TypeCode.UInt16:
          return (T) (ValueType) ushort.Parse(s, NumberStyles.Any, (IFormatProvider) CultureInfo.InvariantCulture);
        case TypeCode.Int32:
          return (T) (ValueType) int.Parse(s, NumberStyles.Any, (IFormatProvider) CultureInfo.InvariantCulture);
        case TypeCode.UInt32:
          return (T) (ValueType) uint.Parse(s, NumberStyles.Any, (IFormatProvider) CultureInfo.InvariantCulture);
        case TypeCode.Single:
          return (T) (ValueType) float.Parse(s, NumberStyles.Any, (IFormatProvider) CultureInfo.InvariantCulture);
        case TypeCode.Double:
          return (T) (ValueType) double.Parse(s, NumberStyles.Any, (IFormatProvider) CultureInfo.InvariantCulture);
        default:
          return default (T);
      }
    }
    catch (FormatException ex)
    {
      return default (T);
    }
  }

  private static bool TryParseDouble(string input, out double parsedValue)
  {
    return double.TryParse(input.Replace(',', '.'), NumberStyles.Any, (IFormatProvider) CultureInfo.InvariantCulture, out parsedValue);
  }

  private static string TimeFormatDouble(double input)
  {
    return input.ToString("0." + new string('0', TxApplication.Options.Units.TimeDigitsAfterDecimalPoint), (IFormatProvider) CultureInfo.InvariantCulture);
  }

  public void PlayForward(string file, PlayModeEnum mode)
  {
    if (this.JumpTimeIndex < this.CurrentTimeIndex && mode == PlayModeEnum.JumpToTime)
      return;
    this._isPlaying = true;
    if (!this._forwardDirection && mode != PlayModeEnum.JumpToTime)
    {
      ++this._currentTimeIndex;
      this._forwardDirection = true;
    }
    switch (mode)
    {
      case PlayModeEnum.StepForward:
        if (this._currentTimeIndex < this._timeList.Count)
        {
          this.PlayForwardFromBackup(mode);
          break;
        }
        this.PlayForwardFromXml(file, mode);
        break;
      case PlayModeEnum.JumpToTime:
        this._jumpTimeReached = false;
        if (this._currentTimeIndex < this._timeList.Count)
          this.PlayForwardFromBackup(mode);
        if (!this._jumpTimeReached)
          this.PlayForwardFromXml(file, mode);
        this._currentTimeIndex = this.JumpTimeIndex;
        this.CurrentTimer = SimulationPlaybackFromXML.TimeFormatDouble(this.IndexToTime[this._currentTimeIndex]);
        Application.DoEvents();
        break;
      default:
        if (this._currentTimeIndex < this._timeList.Count)
          this.PlayForwardFromBackup(mode);
        this.PlayForwardFromXml(file, mode);
        break;
    }
    if (mode == PlayModeEnum.StepForward && this._currentTimeIndex < this._timeNodeList.Count - 1)
    {
      ++this._currentTimeIndex;
      this.NotifyStepForwardEventHandler((object) this, new EventArgs());
    }
    else if (this._isPlaying)
    {
      this._forwardDirection = false;
      this.NotifyPlaybackFinished((object) this, new EventArgs());
    }
    if (mode != PlayModeEnum.JumpToTime)
      this.JumpTimeIndex = this._currentTimeIndex;
    if (mode == PlayModeEnum.JumpToEnd)
      this.CurrentTimer = this.EndTime;
    this._isPlaying = false;
    TxApplication.RefreshDisplay();
  }

  internal void PlayForwardFromBackup(PlayModeEnum mode)
  {
    TxSimulationPlayerEx.SimulationPlaybackIsRunning = true;
    TxPerformanceMeasurementEx.StartMeasureTask(nameof (PlayForwardFromBackup));
    for (int currentTimeIndex = this._currentTimeIndex; currentTimeIndex < this._timeList.Count; ++currentTimeIndex)
    {
      this._currentTimeIndex = currentTimeIndex;
      if (this._isPlaying)
      {
        string input = SimulationPlaybackFromXML.TimeFormatDouble(this.IndexToTime[currentTimeIndex]);
        if (mode != PlayModeEnum.JumpToTime && mode != PlayModeEnum.JumpToEnd)
          this.CurrentTimer = input;
        this._currTimeInterval = SimulationPlaybackFromXML.ParseOrDefault<double>(input);
        if (this._appearanceCreatedBackwardData.ContainsKey(currentTimeIndex))
        {
          foreach (AppearanceRestoreData appearanceRestoreData in this._appearanceCreatedBackwardData[currentTimeIndex])
            this.CreateAppearance(appearanceRestoreData.PmId, appearanceRestoreData.ConsumingOperationId, appearanceRestoreData.Id, appearanceRestoreData.Location);
        }
        if (this._deviceBackwardData.ContainsKey(currentTimeIndex))
        {
          foreach (ITxDevice key in this._deviceBackwardData[currentTimeIndex].Keys)
          {
            if (((ITxObject) key).IsValid())
              TxDeviceEx.SetDevicePoseWithoutObservers(key, this._deviceBackwardData[currentTimeIndex][key].Updated);
          }
        }
        if (this._humanBackwardData.ContainsKey(currentTimeIndex))
        {
          foreach (TxHuman key in this._humanBackwardData[currentTimeIndex].Keys)
          {
            if (((TxBaseGeometryCreationObject) key).IsValid())
              key.SetPosture(this._humanBackwardData[currentTimeIndex][key].Updated);
          }
        }
        if (this._locationBackwardData.ContainsKey(currentTimeIndex))
        {
          foreach (string key in this._locationBackwardData[currentTimeIndex].Keys)
          {
            ITxLocatableObject itxLocatableObject;
            if (this._absoluteLocationData.TryGetValue(key, out itxLocatableObject))
            {
              if (((ITxObject) itxLocatableObject).IsValid())
              {
                try
                {
                  TxLocatableObjectEx.SetTransformationWithoutScopeReadCheck(itxLocatableObject, this._locationBackwardData[currentTimeIndex][key].Updated, true);
                }
                catch (Exception ex)
                {
                }
              }
            }
          }
        }
        if (this._signalsBackwardData.ContainsKey(currentTimeIndex))
        {
          foreach (ITxPlcSignal key in this._signalsBackwardData[currentTimeIndex].Keys)
          {
            if (((ITxObject) key).IsValid())
              key.Value = this._signalsBackwardData[currentTimeIndex][key].Updated;
          }
        }
        if (this._appearanceDeletedBackwardData.ContainsKey(currentTimeIndex))
        {
          foreach (AppearanceRestoreData appearanceRestoreData in this._appearanceDeletedBackwardData[currentTimeIndex])
          {
            ITxOperation itxOperation = (ITxOperation) null;
            ITxLocatableObject itxLocatableObject;
            if (this._absoluteLocationData.TryGetValue(appearanceRestoreData.Id, out itxLocatableObject))
            {
              this._appearances.Remove((ITxObject) itxLocatableObject);
              this._absoluteLocationData.Remove(appearanceRestoreData.Id);
              this._appearancesDummyOps.TryGetValue(appearanceRestoreData.Id, out itxOperation);
              this._appearancesDummyOps.Remove(appearanceRestoreData.Id);
              ((ITxObject) itxLocatableObject)?.Delete();
            }
            ((ITxObject) itxOperation)?.Delete();
            HashSet<string> stringSet;
            if (this._idsOfAppearancesMarkedForInsertion.TryGetValue(appearanceRestoreData.Id, out stringSet))
            {
              foreach (string key in stringSet)
              {
                if (this._appearancesDummyOps.TryGetValue(key, out itxOperation) && ((ITxObject) itxOperation).IsValid())
                  ((ITxObject) itxOperation).Delete();
              }
            }
          }
        }
        switch (mode)
        {
          case PlayModeEnum.PlayForward:
            this.JumpTimeIndex = currentTimeIndex;
            TxApplication.RefreshDisplay();
            if (this.Speed < 100.0)
            {
              Thread.Sleep(new TimeSpan(Convert.ToInt64(100.0 - this.Speed) * 10000L));
              break;
            }
            break;
          case PlayModeEnum.StepForward:
            goto label_65;
          case PlayModeEnum.JumpToTime:
            if (this.JumpTimeIndex == currentTimeIndex)
            {
              this._jumpTimeReached = true;
              goto label_65;
            }
            break;
        }
        Application.DoEvents();
      }
      else
        break;
    }
label_65:
    TxPerformanceMeasurementEx.StopMeasureTask(nameof (PlayForwardFromBackup));
  }

  internal void ReadIdMap()
  {
    this._idTableRootNode = this._xmlDoc.GetElementsByTagName(this.IdMapping);
    if (this._idTableRootNode == null)
      return;
    foreach (XmlNode xmlNode in this._idTableRootNode)
    {
      string key = xmlNode.Attributes.GetNamedItem(this.IdAttribute)?.Value;
      string str = xmlNode.Attributes.GetNamedItem(this.PmIdAttribute)?.Value;
      if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(str) && !this._mapIdToPmId.ContainsKey(key))
        this._mapIdToPmId.Add(key, str);
    }
  }

  public int GetCountTimeTag(string file)
  {
    XmlDocument xmlDocument = new XmlDocument();
    try
    {
      xmlDocument.Load(file);
    }
    catch
    {
      return 0;
    }
    return xmlDocument.GetElementsByTagName(this.TimeTag).Count;
  }

  internal void GetTimeTable(string file = null, XmlNodeList xmlTimeNodeList = null)
  {
    this.IndexToTime.Clear();
    if (xmlTimeNodeList == null)
    {
      TxPerformanceMeasurementEx.StartMeasureTask("LoadXML");
      try
      {
        this._xmlDoc.Load(file);
      }
      catch
      {
        return;
      }
      TxPerformanceMeasurementEx.StopMeasureTask("LoadXML");
      xmlTimeNodeList = this._xmlDoc.GetElementsByTagName(this.TimeTag);
    }
    for (int index = 0; index < xmlTimeNodeList.Count; ++index)
    {
      double orDefault = SimulationPlaybackFromXML.ParseOrDefault<double>(xmlTimeNodeList.Item(index).Attributes.GetNamedItem(this.ValAttribute)?.Value);
      this.IndexToTime.Add(index, orDefault);
    }
    this.EndTime = SimulationPlaybackFromXML.TimeFormatDouble(this.IndexToTime[xmlTimeNodeList.Count - 1]);
    this._firstTimeStr = SimulationPlaybackFromXML.TimeFormatDouble(this.IndexToTime[xmlTimeNodeList.Count == 1 ? 0 : 1]);
    this.OnPropertyChanged("TimeToolTip");
  }

  internal void PlayForwardFromXml(string file, PlayModeEnum mode)
  {
    TxSimulationPlayerEx.SimulationPlaybackIsRunning = true;
    string filePath = this._filePath;
    if ((filePath != null ? filePath.Length : 0) == 0)
    {
      this._filePath = file ?? "";
      if (this._currTimeInterval == 0.0)
      {
        TxPerformanceMeasurementEx.StartMeasureTask("SaveSnapshot");
        this.SaveSnapshot();
        this.ClearAttachments();
        TxPerformanceMeasurementEx.StopMeasureTask("SaveSnapshot");
      }
      TxPerformanceMeasurementEx.StartMeasureTask("LoadXML");
      try
      {
        this._xmlDoc.Load(this._filePath);
      }
      catch (Exception ex)
      {
        int num = (int) TxMessageBox.Show($"{SimulationRecorderAndPlayerStringTable.FAILED_TO_OPEN_FILE}\n{ex.Message}", SimulationRecorderAndPlayerStringTable.MESSAGEBOX_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Hand);
        TxPerformanceMeasurementEx.StopMeasureTask("LoadXML");
        return;
      }
      this._timeNodeList = this._xmlDoc.GetElementsByTagName(this.TimeTag);
      TxPerformanceMeasurementEx.StopMeasureTask("LoadXML");
    }
    this._firstTimeInterval = true;
    TxPerformanceMeasurementEx.StartMeasureTask("RunSimulation");
    string str1 = "";
    this.ReadIdMap();
    if (this._timeNodeList != null)
    {
      for (int currentTimeIndex = this._currentTimeIndex; currentTimeIndex < this._timeNodeList.Count; ++currentTimeIndex)
      {
        this._currentTimeIndex = currentTimeIndex;
        if (this._isPlaying)
        {
          this._jointValue.Clear();
          this._locationValue.Clear();
          this._jointData.Clear();
          this._humanData.Clear();
          this._signalData.Clear();
          this._attachmentData.Clear();
          foreach (ITxHuman key in this._humanJointData.Keys)
            this._humanJointData[key].Clear();
          this._humanJointData.Clear();
          this._drivingJoints.Clear();
          XmlNode xmlNode1 = this._timeNodeList.Item(currentTimeIndex);
          string input1 = xmlNode1.Attributes.GetNamedItem(this.ValAttribute)?.Value;
          double orDefault = SimulationPlaybackFromXML.ParseOrDefault<double>(input1);
          if (mode != PlayModeEnum.JumpToTime && mode != PlayModeEnum.JumpToEnd)
            this.CurrentTimer = SimulationPlaybackFromXML.TimeFormatDouble(orDefault);
          if (orDefault >= this._currTimeInterval)
          {
            if (this._firstTimeInterval)
            {
              this._firstTimeInterval = false;
              str1 = input1;
            }
            this._currTimeInterval = orDefault;
            XmlNode xmlNode2 = xmlNode1.SelectSingleNode(this.AppearancesTag);
            XmlNode xmlNode3 = xmlNode1.SelectSingleNode(this.SignalsTag);
            XmlNode xmlNode4 = xmlNode1.SelectSingleNode(this.JointsTag);
            XmlNode xmlNode5 = xmlNode1.SelectSingleNode(this.LocationsTag);
            XmlNode xmlNode6 = xmlNode1.SelectSingleNode(this.HumansTag);
            XmlNode xmlNode7 = xmlNode1.SelectSingleNode(this.AttachmentsTag);
            if (xmlNode2 != null)
            {
              string consumingOperationId = "";
              foreach (XmlNode childNode in xmlNode2.ChildNodes)
              {
                string key1 = childNode.Attributes.GetNamedItem(this.IdAttribute)?.Value;
                string key2 = childNode.Attributes.GetNamedItem(this.ParentIdAttribute)?.Value;
                string str2;
                this._mapIdToPmId.TryGetValue(key1, out str2);
                consumingOperationId = childNode.Attributes.GetNamedItem(this.ConsumingOperationId)?.Value;
                bool flag = this._absoluteLocationData.TryGetValue(key1, out ITxLocatableObject _);
                if (childNode.Name == this.CreateTag)
                {
                  XmlNode xmlNode8 = childNode.SelectSingleNode(this.LocationTag);
                  if (!flag && !this._idsOfAppearancesMarkedForCreation.ContainsKey(key1))
                    this._idsOfAppearancesMarkedForCreation.Add(key1, new Tuple<string, XmlNode>(str2, xmlNode8));
                }
                else if (childNode.Name == this.DeleteTag)
                {
                  ITxLocatableObject itxLocatableObject;
                  if (this._absoluteLocationData.TryGetValue(key1, out itxLocatableObject))
                  {
                    AppearanceRestoreData appearanceRestoreData = new AppearanceRestoreData();
                    appearanceRestoreData.Id = key1;
                    appearanceRestoreData.PmId = str2;
                    appearanceRestoreData.ConsumingOperationId = consumingOperationId;
                    appearanceRestoreData.Location = itxLocatableObject.AbsoluteLocation;
                    this._appearances.Remove((ITxObject) itxLocatableObject);
                    this._absoluteLocationData.Remove(key1);
                    ITxOperation itxOperation;
                    this._appearancesDummyOps.TryGetValue(key1, out itxOperation);
                    this._appearancesDummyOps.Remove(key1);
                    ((ITxObject) itxLocatableObject).Delete();
                    ((ITxObject) itxOperation)?.Delete();
                    HashSet<string> stringSet;
                    if (this._idsOfAppearancesMarkedForInsertion.TryGetValue(key1, out stringSet))
                    {
                      foreach (string key3 in stringSet)
                      {
                        if (this._appearancesDummyOps.TryGetValue(key3, out itxOperation) && ((ITxObject) itxOperation).IsValid())
                          ((ITxObject) itxOperation).Delete();
                      }
                    }
                    if (!this._appearanceDeletedBackwardData.ContainsKey(currentTimeIndex))
                      this._appearanceDeletedBackwardData.Add(currentTimeIndex, new HashSet<AppearanceRestoreData>());
                    this._appearanceDeletedBackwardData[currentTimeIndex].Add(appearanceRestoreData);
                  }
                }
                else if (childNode.Name == this.InsertTag)
                {
                  HashSet<string> stringSet;
                  if (!this._idsOfAppearancesMarkedForInsertion.TryGetValue(key2, out stringSet))
                  {
                    stringSet = new HashSet<string>();
                    this._idsOfAppearancesMarkedForInsertion.Add(key2, stringSet);
                  }
                  stringSet.Add(key1);
                }
              }
              foreach (string key in this._idsOfAppearancesMarkedForCreation.Keys)
              {
                Tuple<string, XmlNode> tuple;
                if (this._idsOfAppearancesMarkedForCreation.TryGetValue(key, out tuple))
                {
                  if (!(this.ComputeAppearance(tuple.Item1, key, consumingOperationId, tuple.Item2) is ITxLocatableObject appearance))
                  {
                    int num = (int) TxMessageBox.Show("Appearance: Unknown PmId", "SimulationRecorder Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                  }
                  else
                  {
                    AppearanceRestoreData appearanceRestoreData = new AppearanceRestoreData();
                    appearanceRestoreData.Id = key;
                    appearanceRestoreData.PmId = tuple.Item1;
                    appearanceRestoreData.ConsumingOperationId = "";
                    appearanceRestoreData.Location = appearance.AbsoluteLocation;
                    if (!this._appearanceCreatedBackwardData.ContainsKey(currentTimeIndex))
                      this._appearanceCreatedBackwardData.Add(currentTimeIndex, new HashSet<AppearanceRestoreData>());
                    this._appearanceCreatedBackwardData[currentTimeIndex].Add(appearanceRestoreData);
                  }
                }
              }
              this._idsOfAppearancesMarkedForCreation.Clear();
            }
            if (xmlNode3 != null)
            {
              foreach (XmlNode childNode in xmlNode3.ChildNodes)
              {
                string key;
                this._mapIdToPmId.TryGetValue(childNode.Attributes.GetNamedItem(this.IdAttribute)?.Value, out key);
                string input2 = childNode.Attributes.GetNamedItem(this.ValAttribute)?.Value;
                if (!this._signalData.TryGetValue(key, out objectFromIdString) && TxEngineeringDataInternal.GetObjectFromIdString(key) is ITxPlcSignal objectFromIdString)
                  this._signalData.Add(key, objectFromIdString);
                if (objectFromIdString != null)
                {
                  TxPlcValue txPlcValue = new TxPlcValue();
                  switch ((int) objectFromIdString.DataType)
                  {
                    case 0:
                      txPlcValue.BooleanValue = SimulationPlaybackFromXML.ParseOrDefault<bool>(input2);
                      break;
                    case 1:
                      txPlcValue.ByteValue = SimulationPlaybackFromXML.ParseOrDefault<ushort>(input2);
                      break;
                    case 2:
                      txPlcValue.WordValue = SimulationPlaybackFromXML.ParseOrDefault<ushort>(input2);
                      break;
                    case 3:
                      txPlcValue.DWordValue = SimulationPlaybackFromXML.ParseOrDefault<uint>(input2);
                      break;
                    case 4:
                      txPlcValue.IntValue = SimulationPlaybackFromXML.ParseOrDefault<short>(input2);
                      break;
                    case 5:
                      txPlcValue.DIntValue = SimulationPlaybackFromXML.ParseOrDefault<int>(input2);
                      break;
                    case 6:
                      txPlcValue.RealValue = SimulationPlaybackFromXML.ParseOrDefault<float>(input2);
                      break;
                    case 9:
                      txPlcValue.SIntValue = SimulationPlaybackFromXML.ParseOrDefault<sbyte>(input2);
                      break;
                    case 11:
                      txPlcValue.LRealValue = SimulationPlaybackFromXML.ParseOrDefault<double>(input2);
                      break;
                  }
                  if (input1 == str1 && !this._signalValues.ContainsKey(objectFromIdString))
                    this._signalValues.Add(objectFromIdString, objectFromIdString.Value);
                  if (!this._signalsBackwardData.ContainsKey(currentTimeIndex))
                  {
                    Dictionary<ITxPlcSignal, SimulationPlaybackFromXML.PlcValue> dictionary = new Dictionary<ITxPlcSignal, SimulationPlaybackFromXML.PlcValue>();
                    this._signalsBackwardData.Add(currentTimeIndex, dictionary);
                  }
                  if (!this._signalsBackwardData[currentTimeIndex].ContainsKey(objectFromIdString))
                  {
                    SimulationPlaybackFromXML.PlcValue plcValue = new SimulationPlaybackFromXML.PlcValue();
                    this._signalsBackwardData[currentTimeIndex].Add(objectFromIdString, plcValue);
                  }
                  this._signalsBackwardData[currentTimeIndex][objectFromIdString].Original = objectFromIdString.Value;
                  this._signalsBackwardData[currentTimeIndex][objectFromIdString].Updated = txPlcValue;
                  objectFromIdString.Value = txPlcValue;
                }
              }
            }
            if (xmlNode7 != null)
            {
              foreach (XmlNode childNode in xmlNode7.ChildNodes)
              {
                string str3;
                this._mapIdToPmId.TryGetValue(childNode.Attributes.GetNamedItem(this.IdAttribute)?.Value, out str3);
                ITxLocatableObject key = (ITxLocatableObject) null;
                if (!string.IsNullOrEmpty(str3))
                  key = TxEngineeringDataInternal.GetObjectFromIdString(str3) as ITxLocatableObject;
                if (childNode.Name == this.AttachTag)
                {
                  if (key != null)
                  {
                    string str4;
                    this._mapIdToPmId.TryGetValue(childNode.Attributes.GetNamedItem(this.AttachmentParentIdAttribute)?.Value, out str4);
                    ITxLocatableObject itxLocatableObject = (ITxLocatableObject) null;
                    if (!string.IsNullOrEmpty(str4))
                      itxLocatableObject = TxEngineeringDataInternal.GetObjectFromIdString(str4) as ITxLocatableObject;
                    if (this._attachmentData.ContainsKey(key))
                      this._attachmentData[key] = itxLocatableObject;
                    else
                      this._attachmentData.Add(key, itxLocatableObject);
                  }
                }
                else if (childNode.Name == this.DetachTag && key != null && !this._attachmentData.ContainsKey(key))
                  this._attachmentData.Add(key, (ITxLocatableObject) null);
              }
            }
            if (xmlNode6 != null)
            {
              foreach (XmlNode childNode1 in xmlNode6.ChildNodes)
              {
                string key4;
                this._mapIdToPmId.TryGetValue(childNode1.Attributes.GetNamedItem(this.IdAttribute)?.Value, out key4);
                key5 = (ITxHuman) null;
                if (!this._humanData.TryGetValue(key4, out key5) && TxEngineeringDataInternal.GetObjectFromIdString(key4) is ITxHuman key5)
                {
                  this._humanData.Add(key4, key5);
                  Dictionary<string, double> dictionary = new Dictionary<string, double>();
                  this._humanJointData.Add(key5, dictionary);
                }
                if (key5 != null)
                {
                  foreach (XmlNode childNode2 in childNode1.SelectSingleNode(this.HumanJointsTag).ChildNodes)
                  {
                    string key6 = childNode2.Attributes.GetNamedItem(this.NameAttribute)?.Value;
                    double parsedValue;
                    if (SimulationPlaybackFromXML.TryParseDouble(childNode2.Attributes.GetNamedItem(this.ValAttribute)?.Value, out parsedValue))
                    {
                      if (this._humanJointData[key5].ContainsKey(key6))
                        this._humanJointData[key5][key6] = parsedValue;
                      else
                        this._humanJointData[key5].Add(key6, parsedValue);
                    }
                  }
                }
              }
            }
            if (xmlNode4 != null)
            {
              foreach (XmlNode childNode in xmlNode4.ChildNodes)
              {
                string key7;
                this._mapIdToPmId.TryGetValue(childNode.Attributes.GetNamedItem(this.IdAttribute)?.Value, out key7);
                string input3 = childNode.Attributes.GetNamedItem(this.ValAttribute)?.Value;
                TxJoint key8 = (TxJoint) null;
                if (!this._jointData.TryGetValue(key7, out key8))
                {
                  key8 = TxEngineeringDataInternal.GetObjectFromIdString(key7) as TxJoint;
                  if (TxJoint.op_Inequality(key8, (ITxObject) null))
                    this._jointData.Add(key7, key8);
                }
                double parsedValue;
                if (TxJoint.op_Inequality(key8, (ITxObject) null) && SimulationPlaybackFromXML.TryParseDouble(input3, out parsedValue))
                {
                  if (this._jointValue.ContainsKey(key8))
                    this._jointValue[key8] = parsedValue;
                  else
                    this._jointValue.Add(key8, parsedValue);
                }
              }
            }
            if (xmlNode5 != null)
            {
              foreach (XmlNode childNode in xmlNode5.ChildNodes)
                this.HandleLocation(childNode);
            }
            foreach (ITxHuman key9 in this._humanJointData.Keys)
            {
              if (((ITxObject) key9).IsValid())
              {
                TxHuman key10 = key9 as TxHuman;
                TxHumanPosture posture1 = key10.GetPosture();
                TxHumanPosture posture2 = key10.GetPosture();
                if (!this._humanBackwardData.ContainsKey(currentTimeIndex))
                {
                  Dictionary<TxHuman, SimulationPlaybackFromXML.HumanPosture> dictionary = new Dictionary<TxHuman, SimulationPlaybackFromXML.HumanPosture>();
                  this._humanBackwardData.Add(currentTimeIndex, dictionary);
                }
                if (!this._humanBackwardData[currentTimeIndex].ContainsKey(key10))
                {
                  SimulationPlaybackFromXML.HumanPosture humanPosture = new SimulationPlaybackFromXML.HumanPosture();
                  this._humanBackwardData[currentTimeIndex].Add(key10, humanPosture);
                }
                this._humanBackwardData[currentTimeIndex][key10].Original = posture1;
                TxHumanJointData[] joints = posture1.Joints;
                for (int index = 0; index < joints.Length; ++index)
                {
                  string name = joints[index].Name;
                  if (this._humanJointData[key9].ContainsKey(name))
                    joints[index].Value = this._humanJointData[key9][name];
                }
                posture2.Joints = joints;
                this._humanBackwardData[currentTimeIndex][key10].Updated = posture2;
                key10.SetPosture(posture2);
              }
            }
            Dictionary<ITxDevice, ArrayList> dictionary1 = new Dictionary<ITxDevice, ArrayList>();
            foreach (TxJoint key in this._jointValue.Keys)
            {
              ITxDevice device = key.Device;
              if (!this._drivingJoints.ContainsKey(device))
                this._drivingJoints.Add(device, device.DrivingJoints);
              int index = ((Collection<ITxObject>) this._drivingJoints[device]).IndexOf((ITxObject) key);
              if (dictionary1.ContainsKey(device))
              {
                dictionary1[device][index] = (object) this._jointValue[key];
              }
              else
              {
                ArrayList jointValues = device.CurrentPose.JointValues;
                jointValues[index] = (object) this._jointValue[key];
                dictionary1.Add(device, jointValues);
              }
            }
            foreach (ITxDevice key in dictionary1.Keys)
            {
              if (((ITxObject) key).IsValid())
              {
                TxPoseData currentPose1 = key.CurrentPose;
                TxPoseData currentPose2 = key.CurrentPose;
                if (!this._deviceBackwardData.ContainsKey(currentTimeIndex))
                {
                  Dictionary<ITxDevice, SimulationPlaybackFromXML.PoseData> dictionary2 = new Dictionary<ITxDevice, SimulationPlaybackFromXML.PoseData>();
                  this._deviceBackwardData.Add(currentTimeIndex, dictionary2);
                }
                if (!this._deviceBackwardData[currentTimeIndex].ContainsKey(key))
                {
                  SimulationPlaybackFromXML.PoseData poseData = new SimulationPlaybackFromXML.PoseData();
                  this._deviceBackwardData[currentTimeIndex].Add(key, poseData);
                }
                this._deviceBackwardData[currentTimeIndex][key].Original = currentPose1;
                currentPose2.JointValues = dictionary1[key];
                this._deviceBackwardData[currentTimeIndex][key].Updated = currentPose2;
                TxDeviceEx.SetDevicePoseWithoutObservers(key, currentPose2);
              }
            }
            foreach (string key in this._locationValue.Keys)
            {
              ITxLocatableObject itxLocatableObject;
              if (this._absoluteLocationData.TryGetValue(key, out itxLocatableObject) && ((ITxObject) itxLocatableObject).IsValid())
              {
                if (!this._locationBackwardData.ContainsKey(currentTimeIndex))
                {
                  Dictionary<string, SimulationPlaybackFromXML.Transformation> dictionary3 = new Dictionary<string, SimulationPlaybackFromXML.Transformation>();
                  this._locationBackwardData.Add(currentTimeIndex, dictionary3);
                }
                if (!this._locationBackwardData[currentTimeIndex].ContainsKey(key))
                {
                  SimulationPlaybackFromXML.Transformation transformation = new SimulationPlaybackFromXML.Transformation();
                  this._locationBackwardData[currentTimeIndex].Add(key, transformation);
                }
                this._locationBackwardData[currentTimeIndex][key].Original = itxLocatableObject.AbsoluteLocation;
                this._locationBackwardData[currentTimeIndex][key].Updated = this._locationValue[key];
                try
                {
                  TxLocatableObjectEx.SetTransformationWithoutScopeReadCheck(itxLocatableObject, this._locationValue[key], true);
                }
                catch (Exception ex)
                {
                }
              }
            }
            foreach (ITxLocatableObject key in this._attachmentData.Keys)
            {
              if (this._attachmentData[key] != null)
                key.AttachTo(this._attachmentData[key]);
              else
                key.Detach();
            }
            if (this._timeList.Count < this.IndexToTime.Count)
              this._timeList.Add((object) input1);
            this.NotifyPlaybackTimeIntervalReached((object) this, new CTimeIntervalReachedEventArgs(this._currTimeInterval));
            switch (mode)
            {
              case PlayModeEnum.PlayForward:
                this.JumpTimeIndex = currentTimeIndex;
                TxApplication.RefreshDisplay();
                if (this.Speed < 100.0)
                {
                  Thread.Sleep(new TimeSpan(Convert.ToInt64(100.0 - this.Speed) * 10000L));
                  break;
                }
                break;
              case PlayModeEnum.StepForward:
                goto label_209;
              case PlayModeEnum.JumpToTime:
                if (this.JumpTimeIndex == currentTimeIndex)
                {
                  this._jumpTimeReached = true;
                  this._currentTimeIndex = this.JumpTimeIndex;
                  goto label_209;
                }
                break;
            }
            Application.DoEvents();
          }
        }
        else
          break;
      }
    }
label_209:
    TxPerformanceMeasurementEx.StopMeasureTask("RunSimulation");
  }

  private void ClearAttachments()
  {
    foreach (ITxObject allDescendant in (Collection<ITxObject>) TxApplication.ActiveDocument.PhysicalRoot.GetAllDescendants((ITxTypeFilter) new TxTypeFilter(new Type[6]
    {
      typeof (ITxComponent),
      typeof (ITxSafetyObject),
      typeof (ITxLocationOperation),
      typeof (TxFrame),
      typeof (TxPartAppearance),
      typeof (ITxSkidAppearance)
    }, new Type[0])))
    {
      if (allDescendant is ITxLocatableObject itxLocatableObject && itxLocatableObject.AttachmentParent != null)
        itxLocatableObject.Detach();
    }
  }

  internal void PlayBackward(PlayModeEnum mode)
  {
    TxPerformanceMeasurementEx.StartMeasureTask(nameof (PlayBackward));
    if (this.JumpTimeIndex > this.CurrentTimeIndex && mode == PlayModeEnum.JumpToTime)
      return;
    TxSimulationPlayerEx.SimulationPlaybackIsRunning = true;
    this._isPlaying = true;
    bool flag = false;
    if (this._forwardDirection && mode != PlayModeEnum.JumpToTime)
      --this._currentTimeIndex;
    this._forwardDirection = false;
    this._jumpTimeReached = false;
    for (; this._currentTimeIndex >= 0 && this._isPlaying && !flag; --this._currentTimeIndex)
    {
      string input = SimulationPlaybackFromXML.TimeFormatDouble(this.IndexToTime[this._currentTimeIndex]);
      if (mode != PlayModeEnum.JumpToTime)
        this.CurrentTimer = input;
      this._currTimeInterval = SimulationPlaybackFromXML.ParseOrDefault<double>(input);
      if (this._appearanceDeletedBackwardData.ContainsKey(this._currentTimeIndex))
      {
        foreach (AppearanceRestoreData appearanceRestoreData in this._appearanceDeletedBackwardData[this._currentTimeIndex])
          this.CreateAppearance(appearanceRestoreData.PmId, appearanceRestoreData.ConsumingOperationId, appearanceRestoreData.Id, appearanceRestoreData.Location);
      }
      if (this._deviceBackwardData.ContainsKey(this._currentTimeIndex))
      {
        foreach (ITxDevice key in this._deviceBackwardData[this._currentTimeIndex].Keys)
        {
          if (((ITxObject) key).IsValid())
            TxDeviceEx.SetDevicePoseWithoutObservers(key, this._deviceBackwardData[this._currentTimeIndex][key].Original);
        }
      }
      if (this._humanBackwardData.ContainsKey(this._currentTimeIndex))
      {
        foreach (TxHuman key in this._humanBackwardData[this._currentTimeIndex].Keys)
        {
          if (((TxBaseGeometryCreationObject) key).IsValid())
            key.SetPosture(this._humanBackwardData[this._currentTimeIndex][key].Original);
        }
      }
      if (this._locationBackwardData.ContainsKey(this._currentTimeIndex))
      {
        foreach (string key in this._locationBackwardData[this._currentTimeIndex].Keys)
        {
          ITxLocatableObject itxLocatableObject;
          if (this._absoluteLocationData.TryGetValue(key, out itxLocatableObject))
          {
            if (((ITxObject) itxLocatableObject).IsValid())
            {
              try
              {
                TxLocatableObjectEx.SetTransformationWithoutScopeReadCheck(itxLocatableObject, this._locationBackwardData[this._currentTimeIndex][key].Updated, true);
              }
              catch (Exception ex)
              {
              }
            }
          }
        }
      }
      if (this._signalsBackwardData.ContainsKey(this._currentTimeIndex))
      {
        foreach (ITxPlcSignal key in this._signalsBackwardData[this._currentTimeIndex].Keys)
        {
          if (((ITxObject) key).IsValid())
            key.Value = this._signalsBackwardData[this._currentTimeIndex][key].Original;
        }
      }
      if (this._appearanceCreatedBackwardData.ContainsKey(this._currentTimeIndex))
      {
        foreach (AppearanceRestoreData appearanceRestoreData in this._appearanceCreatedBackwardData[this._currentTimeIndex])
        {
          ITxOperation itxOperation = (ITxOperation) null;
          ITxLocatableObject itxLocatableObject1;
          if (this._absoluteLocationData.TryGetValue(appearanceRestoreData.Id, out itxLocatableObject1))
          {
            this._appearances.Remove((ITxObject) itxLocatableObject1);
            this._absoluteLocationData.Remove(appearanceRestoreData.Id);
            this._appearancesDummyOps.TryGetValue(appearanceRestoreData.Id, out itxOperation);
            this._appearancesDummyOps.Remove(appearanceRestoreData.Id);
          }
          HashSet<string> stringSet;
          if (itxLocatableObject1 is TxPartAppearance txPartAppearance && this._idsOfAppearancesMarkedForInsertion.TryGetValue(appearanceRestoreData.Id, out stringSet))
          {
            TxObjectList txObjectList = new TxObjectList();
            foreach (string key in stringSet)
            {
              ITxLocatableObject itxLocatableObject2;
              if (this._absoluteLocationData.TryGetValue(key, out itxLocatableObject2))
                ((Collection<ITxObject>) txObjectList).Add((ITxObject) itxLocatableObject2);
            }
            TxPartPhysicalAppearanceExtensions.DisassociateChildrenAndDelete(txPartAppearance, txObjectList);
          }
          else
            ((ITxObject) itxLocatableObject1)?.Delete();
          ((ITxObject) itxOperation)?.Delete();
        }
      }
      switch (mode)
      {
        case PlayModeEnum.StepBackward:
          flag = true;
          this.JumpTimeIndex = this._currentTimeIndex;
          break;
        case PlayModeEnum.PlayBackward:
          this.JumpTimeIndex = this._currentTimeIndex;
          TxApplication.RefreshDisplay();
          if (this.Speed < 100.0)
          {
            Thread.Sleep(new TimeSpan(Convert.ToInt64(100.0 - this.Speed) * 10000L));
            break;
          }
          break;
        case PlayModeEnum.JumpToTime:
          if (this.JumpTimeIndex == this._currentTimeIndex)
          {
            this.CurrentTimer = SimulationPlaybackFromXML.TimeFormatDouble(this.IndexToTime[this.JumpTimeIndex]);
            Application.DoEvents();
            goto label_70;
          }
          break;
      }
      Application.DoEvents();
    }
label_70:
    if (mode == PlayModeEnum.StepBackward && this._currentTimeIndex >= 0)
      this.NotifyStepBackwardEventHandler((object) this, new EventArgs());
    else if (this._isPlaying)
    {
      this._forwardDirection = true;
      this.NotifyPlaybackBackwardFinished((object) this, new EventArgs());
    }
    if (this._currentTimeIndex < 0)
      this._currentTimeIndex = 0;
    this._isPlaying = false;
    TxApplication.RefreshDisplay();
    TxPerformanceMeasurementEx.StopMeasureTask(nameof (PlayBackward));
  }

  private ITxObject CreatePartAppearanceForConsumingOperationId(
    string consumingOperationId,
    string appearancePmId,
    string partAppearanceIndexId)
  {
    ITxObject consumingOperationId1 = (ITxObject) null;
    ITxOperation containeroperation = this.CreateAppendContaineroperation();
    if (containeroperation != null)
    {
      (containeroperation as ITxDisplayableObject).Blank();
      ITxPlanningObject planningObjectById = this.GetPlanningObjectById(new TxProcessModelId(appearancePmId));
      if (planningObjectById != null)
      {
        ((ITxObject) containeroperation).Name = "dummy operation for " + ((ITxObject) planningObjectById).Name;
        new TxOperationEx(containeroperation)?.ComputePartLogicalAppearance((ITxObject) planningObjectById);
        HashSet<string> stringSet;
        if (!this._idsOfAppearancesMarkedForInsertion.TryGetValue(partAppearanceIndexId, out stringSet))
        {
          consumingOperationId1 = (ITxObject) TxEngineeringDataInternal.GenerateLineSimulationPartAppearance(containeroperation, planningObjectById);
        }
        else
        {
          ArrayList arrayList = new ArrayList(stringSet.Count);
          foreach (string key in stringSet)
          {
            ITxLocatableObject itxLocatableObject;
            if (this._absoluteLocationData.TryGetValue(key, out itxLocatableObject))
              arrayList.Add((object) itxLocatableObject);
          }
          consumingOperationId1 = (ITxObject) TxEngineeringDataInternal.GenerateLineSimulationPartAppearance(containeroperation, arrayList, planningObjectById);
        }
      }
    }
    if (consumingOperationId1 is ITxPartAppearance itxPartAppearance)
    {
      ITxPlanningObject originPart = itxPartAppearance.OriginPart;
      if (originPart != null && originPart.ProcessModelId.ExternalId == appearancePmId)
      {
        this._appearances.Add(consumingOperationId1);
        this._absoluteLocationData.Add(partAppearanceIndexId, consumingOperationId1 as ITxLocatableObject);
        this._appearancesDummyOps.Add(partAppearanceIndexId, containeroperation);
      }
    }
    return consumingOperationId1;
  }

  private ITxObject CreateSkidAppearance(
    string appearanceId,
    TxPlanningResource originalResource,
    TxTransformation absLoc)
  {
    ITxObject skidAppearance = (ITxObject) null;
    if (((TxPlanningObject) originalResource).EngineeringRepresentation is ITxComponent engineeringRepresentation)
    {
      TxTransformation txTransformation = TxTransformation.op_Inequality(absLoc, (TxTransformation) null) ? absLoc : new TxTransformation();
      skidAppearance = (ITxObject) TxEngineeringDataInternal.GenerateSkidAppearance(engineeringRepresentation, txTransformation);
      this._appearances.Add(skidAppearance);
      try
      {
        this._absoluteLocationData.Add(appearanceId, skidAppearance as ITxLocatableObject);
      }
      catch (ArgumentException ex)
      {
        this._appearances.Remove(skidAppearance);
      }
    }
    return skidAppearance;
  }

  private ITxLocatableObject CreateAppearance(
    string appearancePmId,
    string consumingOperationId,
    string appearanceId,
    TxTransformation absLocation)
  {
    appearance = (ITxLocatableObject) null;
    ITxObject itxObject = (ITxObject) null;
    if (appearancePmId != null)
      itxObject = (ITxObject) this.GetPlanningObjectById(new TxProcessModelId(appearancePmId));
    if (itxObject is TxPlanningPart)
    {
      if (this.CreatePartAppearanceForConsumingOperationId(consumingOperationId, appearancePmId, appearanceId) is ITxLocatableObject appearance)
      {
        try
        {
          TxLocatableObjectEx.SetTransformationWithoutScopeReadCheck(appearance, absLocation, true);
        }
        catch (Exception ex)
        {
        }
      }
    }
    if (itxObject is TxPlanningResource originalResource)
      appearance = this.CreateSkidAppearance(appearanceId, originalResource, absLocation) as ITxLocatableObject;
    return appearance;
  }

  private ITxObject ComputeAppearance(
    string appearancePmId,
    string appearanceId,
    string consumingOperationId,
    XmlNode locationNode)
  {
    ITxLocatableObject appearance;
    if (!this._absoluteLocationData.TryGetValue(appearanceId, out appearance))
    {
      TxTransformation fromLocationNode = this.GetPostionFromLocationNode(locationNode);
      appearance = this.CreateAppearance(appearancePmId, consumingOperationId, appearanceId, fromLocationNode);
    }
    return (ITxObject) appearance;
  }

  private void HandleLocation(XmlNode locationElement)
  {
    string key = locationElement.Attributes.GetNamedItem(this.IdAttribute)?.Value;
    string str;
    this._mapIdToPmId.TryGetValue(key, out str);
    itxLocatableObject = (ITxLocatableObject) null;
    if (!string.IsNullOrEmpty(key) && !this._absoluteLocationData.TryGetValue(key, out itxLocatableObject) && !string.IsNullOrEmpty(str) && TxEngineeringDataInternal.GetObjectFromIdString(str) is ITxLocatableObject itxLocatableObject)
      this._absoluteLocationData.Add(key, itxLocatableObject);
    if (itxLocatableObject == null)
      return;
    TxTransformation fromLocationNode = this.GetPostionFromLocationNode(locationElement);
    if (!TxTransformation.op_Inequality(fromLocationNode, (TxTransformation) null))
      return;
    if (this._locationValue.ContainsKey(key))
      this._locationValue[key] = fromLocationNode;
    else
      this._locationValue.Add(key, fromLocationNode);
  }

  private void SaveSnapshot()
  {
    if (TxSnapshot.op_Inequality(this._snapshot, (ITxObject) null) && this._snapshot.IsValid())
      this._snapshot.Delete();
    this._snapshot = TxApplication.ActiveDocument.PhysicalRoot.CreateSnapshot(new TxSnapshotCreationData()
    {
      Name = this.SnapshotName
    });
  }

  private void ApplySnapshot()
  {
    this._snapshot?.Apply(new TxApplySnapshotParams()
    {
      ObjectsLocation = true,
      ObjectsVisibility = true,
      DevicePoses = true,
      ObjectsAttachments = true,
      ObjectsColor = true,
      ObjectsViewingMode = true,
      PMIsScale = true
    });
    foreach (ITxPlcSignal key in this._signalValues.Keys)
    {
      if (((ITxObject) key).IsValid())
        key.Value = this._signalValues[key];
    }
    this._signalValues.Clear();
    foreach (ITxObject appearance in this._appearances)
      appearance.Delete();
    foreach (ITxObject itxObject in this._appearancesDummyOps.Values)
      itxObject.Delete();
    this._appearancesDummyOps.Clear();
    this._appearances.Clear();
    this._idsOfAppearancesMarkedForCreation.Clear();
    this._idsOfAppearancesMarkedForInsertion.Clear();
    this._jointValue.Clear();
    this._locationValue.Clear();
    this._jointData.Clear();
    this._absoluteLocationData.Clear();
    this._attachmentData.Clear();
    this._humanData.Clear();
    this._signalData.Clear();
    foreach (ITxHuman key in this._humanJointData.Keys)
      this._humanJointData[key].Clear();
    this._humanJointData.Clear();
    this._drivingJoints.Clear();
    this._timeList.Clear();
    this._mapIdToPmId.Clear();
    foreach (int key in this._humanBackwardData.Keys)
      this._humanBackwardData[key].Clear();
    this._humanBackwardData.Clear();
    foreach (int key in this._locationBackwardData.Keys)
      this._locationBackwardData[key].Clear();
    this._locationBackwardData.Clear();
    foreach (int key in this._deviceBackwardData.Keys)
      this._deviceBackwardData[key].Clear();
    this._deviceBackwardData.Clear();
    foreach (int key in this._signalsBackwardData.Keys)
      this._signalsBackwardData[key].Clear();
    this._signalsBackwardData.Clear();
    foreach (int key in this._appearanceCreatedBackwardData.Keys)
      this._appearanceCreatedBackwardData[key].Clear();
    this._appearanceCreatedBackwardData.Clear();
    foreach (int key in this._appearanceDeletedBackwardData.Keys)
      this._appearanceDeletedBackwardData[key].Clear();
    this._appearanceDeletedBackwardData.Clear();
  }

  internal void Pause() => this._isPlaying = false;

  internal void Reset()
  {
    this.ApplySnapshot();
    this._currTimeInterval = 0.0;
    this._currentTimeIndex = 0;
    this._forwardDirection = true;
    this.JumpTimeIndex = 0;
    TxSimulationPlayerEx.SimulationPlaybackIsRunning = false;
  }

  protected void NotifyPlaybackFinished(object sender, EventArgs e)
  {
    if (this.PlaybackFinished == null)
      return;
    this.PlaybackFinished(sender, e);
  }

  protected void NotifyPlaybackTimeIntervalReached(object sender, CTimeIntervalReachedEventArgs e)
  {
    if (this.PlaybackTimeIntervalReached == null)
      return;
    this.PlaybackTimeIntervalReached(sender, e);
  }

  protected void NotifyPlaybackBackwardFinished(object sender, EventArgs e)
  {
    if (this.PlaybackBackwardFinished == null)
      return;
    this.PlaybackBackwardFinished(sender, e);
  }

  protected void NotifyStepForwardEventHandler(object sender, EventArgs e)
  {
    if (this.StepForward == null)
      return;
    this.StepForward(sender, e);
  }

  protected void NotifyStepBackwardEventHandler(object sender, EventArgs e)
  {
    if (this.StepBackward == null)
      return;
    this.StepBackward(sender, e);
  }

  private TxTransformation GetPostionFromLocationNode(XmlNode locationNode)
  {
    TxTransformation fromLocationNode = (TxTransformation) null;
    string input1 = locationNode.Attributes.GetNamedItem(this.RX_Tag)?.Value;
    string input2 = locationNode.Attributes.GetNamedItem(this.RY_Tag)?.Value;
    string input3 = locationNode.Attributes.GetNamedItem(this.RZ_Tag)?.Value;
    string input4 = locationNode.Attributes.GetNamedItem(this.X_Tag)?.Value;
    string input5 = locationNode.Attributes.GetNamedItem(this.Y_Tag)?.Value;
    string input6 = locationNode.Attributes.GetNamedItem(this.Z_Tag)?.Value;
    double parsedValue1;
    double parsedValue2;
    double parsedValue3;
    double parsedValue4;
    double parsedValue5;
    double parsedValue6;
    if (SimulationPlaybackFromXML.TryParseDouble(input4, out parsedValue1) && SimulationPlaybackFromXML.TryParseDouble(input5, out parsedValue2) && SimulationPlaybackFromXML.TryParseDouble(input6, out parsedValue3) && SimulationPlaybackFromXML.TryParseDouble(input1, out parsedValue4) && SimulationPlaybackFromXML.TryParseDouble(input2, out parsedValue5) && SimulationPlaybackFromXML.TryParseDouble(input3, out parsedValue6))
      fromLocationNode = new TxTransformation(new TxVector(parsedValue1, parsedValue2, parsedValue3), new TxVector(parsedValue4, parsedValue5, parsedValue6), (TxTransformation.TxRotationType) 1);
    return fromLocationNode;
  }

  private ITxPlanningObject GetPlanningObjectById(TxProcessModelId id)
  {
    ITxPlanningObject planningObjectById = (ITxPlanningObject) null;
    if (this.TeamCenterMode)
    {
      planningObjectById = ((ITxOfflineGlobalServicesProvider) new TxOfflineGlobalServicesProvider()).GetObjectByProcessModelId(id);
    }
    else
    {
      switch (TxApplication.ActiveDocument.PlatformGlobalServicesProvider)
      {
        case ITxEmsGlobalServicesProvider servicesProvider1:
          planningObjectById = servicesProvider1.GetObjectByProcessModelId(id);
          break;
        case ITxOfflineGlobalServicesProvider servicesProvider2:
          planningObjectById = servicesProvider2.GetObjectByProcessModelId(id);
          break;
      }
    }
    return planningObjectById;
  }

  private ITxOperation CreateAppendContaineroperation()
  {
    TxCompoundOperationCreationData operationCreationData = new TxCompoundOperationCreationData();
    operationCreationData.SetAsDisplay();
    return (ITxOperation) TxApplication.ActiveDocument.OperationRoot.CreateCompoundOperation(operationCreationData);
  }

  internal void PlayForwardFromXmlExternal(string file)
  {
    this._isPlaying = true;
    this.FilePath = "";
    this._currentTimeIndex = 0;
    this.PlayForwardFromXml(file, PlayModeEnum.PlayForward);
  }

  internal void JumpToTimeExternal(string file, double time)
  {
    this.JumpTimeIndex = Math.Abs(new List<double>((IEnumerable<double>) this.IndexToTime.Values).BinarySearch(time));
    if (this.JumpTimeIndex > this._currentTimeIndex)
    {
      this.PlayForward(file, PlayModeEnum.JumpToTime);
    }
    else
    {
      if (this.JumpTimeIndex >= this._currentTimeIndex)
        return;
      this.PlayBackward(PlayModeEnum.JumpToTime);
    }
  }

  internal void ClearRecordings()
  {
    if (!TxSnapshot.op_Inequality(this._snapshot, (ITxObject) null) || !this._snapshot.IsValid())
      return;
    this._snapshot.Delete();
  }

  public delegate void PlaybackFinishedEventHandler(object sender, EventArgs args);

  public delegate void PlaybackTimeIntervalReachedEventHandler(
    object sender,
    CTimeIntervalReachedEventArgs args);

  public delegate void PlaybackBackwardFinishedEventHandler(object sender, EventArgs args);

  public delegate void StepForwardEventHandler(object sender, EventArgs args);

  public delegate void StepBackwardEventHandler(object sender, EventArgs args);

  private class PoseData
  {
    public TxPoseData Original { get; set; }

    public TxPoseData Updated { get; set; }
  }

  private class HumanPosture
  {
    public TxHumanPosture Original { get; set; }

    public TxHumanPosture Updated { get; set; }
  }

  private class Transformation
  {
    public TxTransformation Original { get; set; }

    public TxTransformation Updated { get; set; }
  }

  private class PlcValue
  {
    public TxPlcValue Original { get; set; }

    public TxPlcValue Updated { get; set; }
  }
}
